package cool.mtc.security.service.impl;

import cool.mtc.core.exception.CustomException;
import cool.mtc.core.result.ResultConstant;
import cool.mtc.security.data.model.UserDetailsSupport;
import cool.mtc.security.service.PermissionService;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * @author 明河
 */
public class PermissionServiceImpl implements PermissionService {
    private static final Map<String, Pattern> PATTERN_MAP = new HashMap<>();

    @Override
    public boolean hasRole(String... roleCodes) {
        UserDetailsSupport user = this.getUserDetailsSupport();
        boolean hasRole = false;
        for (String item : user.getRoleList()) {
            if (Arrays.asList(roleCodes).contains(item)) {
                hasRole = true;
                break;
            }
        }
        if (hasRole) {
            return true;
        }
        throw new CustomException(ResultConstant.A0301);
    }

    @Override
    public boolean hasPermission(String permission) {
        UserDetailsSupport user = this.getUserDetailsSupport();
        boolean hasPermission = false;
        for (String item : user.getPermissionList()) {
            if (item.contains("*")) {
                if (!PATTERN_MAP.containsKey(item)) {
                    PATTERN_MAP.put(item, Pattern.compile(item.replace("*", ".*")));
                }
                hasPermission = PATTERN_MAP.get(item).matcher(permission).matches();
            } else {
                hasPermission = item.equals(permission);
            }
            if (hasPermission) {
                break;
            }
        }
        if (hasPermission) {
            return true;
        }
        throw new CustomException(ResultConstant.A0301);
    }

    private UserDetailsSupport getUserDetailsSupport() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return (UserDetailsSupport) authentication.getDetails();
    }
}
